package at.gv.bmwf.fons.model.ontology.static_impl;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

import at.gv.bmwf.fons.model.ontology.Atom;
import at.gv.bmwf.fons.model.ontology.AtomFactory;
import at.gv.bmwf.fons.model.ontology.Selection;
import at.gv.bmwf.fons.model.ontology.uris.VONT;

import com.google.common.collect.Sets;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDFS;

public class StaticSelection extends StaticNamedResource implements Selection {
	private final String name;
	private final Set<Atom> atoms;
	
	private final AtomFactory atomFactory;
		
	public StaticSelection (Resource resource, AtomFactory atomFactory) {
		super(resource);
		this.atomFactory = atomFactory;
		this.name = resource.getProperty(RDFS.label).getString();
		
		atoms = populateAtoms();
		
		/*System.out.println("This selection (" + getName() + ") selects: ");
		String selectionQuery = "SELECT DISTINCT ?atom ?selectionType ?atomType ?facet ?facetCategory ?facetStructure ?fieldName WHERE {" +
				"<" + getResource() + "> a ?selectionType." +
				"?selectionType <" + OWL.intersectionOf + "> " +
						"( <" + VONT.prefix + "ComplexSelection> " +
								"[ a <" + OWL.Restriction + "> ; <" +
									OWL.onProperty + "> <" + VONT.selectsAtom + "> ;" +
									"<"+ OWL.allValuesFrom +"> ?atomType ] ) . " +
				"<" + getResource() + "> <" + VONT.selectsAtom + "> ?atom." +
				"?atom a ?atomType." + 
				"?atomType <" + RDFS.subClassOf + "> <" + VONT.Atom + ">." +
				"?atom <" + VONT.hasFacet + "> ?facet. " +

				"?facet a ?facetCategory." +
				"?facetCategory <" + RDFS.subClassOf + "> <" + VONT.prefix + "CategorialFacet>." +
				"?facet a ?facetStructure." +
				"?facetCategory <" + RDFS.subClassOf + "> <" + VONT.prefix + "StructuralFacet>." +
				
				"OPTIONAL {?facet <" + VONT.prefix + "field> ?field." +
				"?field <" + RDFS.label + "> ?fieldName.}" +
				
				"}";
		
		ResultSet results = execSelect(selectionQuery);
		StringBuilder answer = new StringBuilder();
		while (results.hasNext()) {
			QuerySolution solution = results.next();
			answer.append("\nAtom: " + solution.get("?atom") + " a " + solution.get("?atomType") + " for a " + 
					solution.get("?selectionType") + " faceted as: " + solution.get("?facet")
					+ " (which is a " + solution.get("?facetCategory") + " and a " + solution.get("?facetStructure")
					+ (solution.contains("?fieldName") ? solution.get("?fieldName") : "") + ")");
		}
		System.out.println(answer.toString());*/
		
//		commonFacets = populateFacets(
//			String.format("SELECT (COUNT(DISTINCT ?atom) as ?atoms) ?facet WHERE {" +
//				"<%s> <%s> ?facet. <%s> <%s> ?atom. ?atom <%s> ?facet. } " +
//				"GROUP BY ?facet HAVING (?atoms = " + atoms.size() + ")",
//				getResource(), VONT.selectsFacet, getResource(), VONT.selectsAtom, VONT.hasFacet));
//		
//		groupFacets = populateFacets(
//			String.format("SELECT (COUNT(DISTINCT ?atom) as ?atoms) ?facet WHERE {" +
//				"<%s> <%s> ?facet. <%s> <%s> ?atom. ?atom <%s> ?facet. } " +
//				"GROUP BY ?facet HAVING (?atoms < " + atoms.size() + " && ?atoms > 1)",
//				getResource(), VONT.selectsFacet, getResource(), VONT.selectsAtom, VONT.hasFacet));
	}
	
//	private Set<Facet> populateFacets(String queryString) {
//		final Set<Facet> facets = Sets.newHashSet();
//		ResultSet result = execSelect(queryString);
//		while (result.hasNext()) {
//			QuerySolution solution = result.next();
//			facets.add(new StaticFacet(solution.getResource("?facet")));
//		}
//		
//		return facets;
//	}

	private Set<Atom> populateAtoms() {
/*		final Set<Atom> atoms = Sets.newHashSet();
		String queryString = String.format("SELECT ?atom WHERE {" +
				"<%s> <%s> ?atom } ", getResource(), VONT.selectsAtom);
			
		ResultSet result = execSelect(queryString);
		while (result.hasNext()) {
			QuerySolution solution = result.next();
			atoms.add(new StaticAtom(solution.getResource("?atom")));
		}
		return atoms;*/
		return atomFactory.load(this);
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public Collection<Atom> getAtoms() {
		return Collections.unmodifiableSet(atoms);
	}

//	@Override
//	public Collection<Facet> getAllFacets() {
//		return Sets.union(commonFacets, groupFacets);
//	}
//
//	@Override
//	public Collection<Facet> getCommonFacets() {
//		return Collections.unmodifiableSet(commonFacets);
//	}
//
//	@Override
//	public Collection<Facet> getGroupFacets() {
//		return Collections.unmodifiableSet(groupFacets);
//	}

	@Override
	public int compareTo(Selection other) {
		return this.getResource().getURI().compareTo(other.getResource().getURI());
	}
}
